package com.smsc.headend.task.engine.handler.impl.dcuparam;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.StrUtil;
import com.smsc.headend.common.enums.errorcode.TaskHandlerErrorCode;
import com.smsc.headend.common.utils.RedisKeys;
import com.smsc.headend.common.utils.RedisUtils;
import com.smsc.headend.module.asset.dto.DcuMeterTaskDto;
import com.smsc.headend.module.data.enums.OperationGroup;
import com.smsc.headend.module.data.enums.OperationName;
import com.smsc.headend.module.protocol.DeviceData;
import com.smsc.headend.module.protocol.cosem.bo.CosemData;
import com.smsc.headend.module.task.dto.AtomicTask;
import com.smsc.headend.module.task.dto.Task;
import com.smsc.headend.task.engine.dao.TaskDAO;
import com.smsc.headend.task.engine.exception.UDISTaskHandlerException;
import com.smsc.headend.task.engine.handler.TaskHandler;
import com.smsc.headend.task.engine.service.CosemXmlService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.ArrayList;
import java.util.List;

import static com.smsc.headend.task.engine.utils.StepKeyUtil.getStepKey;


/**
 * @author wxh
 * @date 2020/12/15 20:23
 */
@Slf4j
public class ReadDcuMeterTaskHandler implements TaskHandler {
    @Autowired
    TaskDAO taskDAO;
    @Autowired
    CosemXmlService cosemXmlService;
    @Autowired
    RedisUtils redisUtils;

    @Override
    public int handle(Task task, AtomicTask atomicTask, DeviceData deviceData, String actionResult) throws UDISTaskHandlerException {
        if (!(deviceData instanceof CosemData)) {
            throw new UDISTaskHandlerException(TaskHandlerErrorCode.DEVICE_DATA_TYPE_NOT_SUPPORT.toString());
        }

        CosemData cosemData = (CosemData) deviceData;

        List<DcuMeterTaskDto> meterTaskDtos = new ArrayList<>();
        List<String> meterSerialNos = new ArrayList<>();
        if (CollUtil.isNotEmpty(cosemData.getChild())) {
            for (int i = 0; i < cosemData.getChild().size(); i++) {
                DcuMeterTaskDto dto = new DcuMeterTaskDto();
                CosemData structData = cosemData.getChild().get(i);

                CosemData meterSerialNoData = structData.getChild().get(0);
                String meterSerialNo = (String) cosemXmlService.getData(meterSerialNoData.getType(), meterSerialNoData.getValue());
                dto.setMeterSerialNo(meterSerialNo);
                meterSerialNos.add(StrUtil.isEmpty(dto.getMeterSerialNo()) ? "allMeter" : dto.getMeterSerialNo());
                CosemData taskNosData = structData.getChild().get(1);
                List<Long> taskNoList = new ArrayList<>();
                if (CollUtil.isNotEmpty(taskNosData.getChild())) {
                    for (CosemData taskNoData : taskNosData.getChild()) {
                        Long taskNo = Convert.toLong(cosemXmlService.getData(taskNoData.getType(), taskNoData.getValue()));
                        taskNoList.add(taskNo);
                    }
                }
                dto.setTaskNos(taskNoList);

                meterTaskDtos.add(dto);
            }
        }
        if (atomicTask.getGroupId().longValue() == OperationGroup.DcuGetCollScheme.getId() && atomicTask.getOperationId().intValue() == OperationName.GetDcuMeterTask.getId()){
            // Dcu 召测采集方案时返回数据给redis web取redis数据
            taskDAO.addTaskData(task.getTaskNo(), atomicTask.getAtomicTaskNo(), "dcuMeterTaskList", meterTaskDtos, 600L, true);
        }
        if (atomicTask.getGroupId().longValue() == OperationGroup.DcuSetCollScheme.getId() && atomicTask.getOperationId().intValue() == OperationName.GetDcuMeterTask.getId()){
            // Dcu 下发采集方案时 1.获取meterTask 2.清除meterTask 3.下发采集方案 4.下发meterTask
//           这里第一步把meterSerialNos存到redis里面
            redisUtils.hset(RedisKeys.getDcuCollMeterTaskMeterNosKey(task.getTaskNo()), "1", meterSerialNos, 600);
        }
        return 1;
    }

    @Override
    public int handleFailure(Task task, AtomicTask atomicTask, String message) {
        log.info("error {}, ", message);
        if (atomicTask.getGroupId() == OperationGroup.DcuGetCollScheme.getId().intValue()) {
            String stepOperationName = getStepKey(atomicTask, task);
            if (task.getIsODR()) {
                taskDAO.addTaskData(task.getTaskNo(), atomicTask.getAtomicTaskNo(), stepOperationName, String.format("[%s]", message), 3600l, false);
            }
        }
        return -1;
    }
}
